package com.chenc.javathreads.controlleraop.aspect;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.json.JSONUtil;
import com.chenc.javathreads.controlleraop.dto.OperationLogDto;
import com.chenc.javathreads.controlleraop.service.OperationLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * @ClassName
 * @Describtion:
 * @Author:Chenc
 * @Date:2023/12/16 21:04
 * @Version 1.0
 */
//@Component
@Aspect
@Slf4j
public class LogControllerAop {

    @Resource
    private OperationLogService operationLogService;

    @Value("${spring.application.name}")
    private String applicationName;

    @Pointcut(value = "@annotation(com.chenc.javathreads.controlleraop.aspect.ControllerLog)")
    public void cutService(){

    }

    @Around("cutService()")
    public Object recordSysLog(ProceedingJoinPoint point)throws  Throwable{
        Long startTime = System.currentTimeMillis();
        //先执行业务
        Object result = point.proceed();
        Long endTime = System.currentTimeMillis();
        try{
            handle(point,endTime-startTime,"userInfo", JSONUtil.toJsonStr(result),null);
        }catch(Exception e){
            log.info("日志记录出错");
        }
        return result;
    }

    @Before("cutService()")
    public void beforeSysLog(JoinPoint point)throws  Throwable{
        Object[] args = point.getArgs();
        String kind = point.getKind();

    }


    @AfterThrowing(pointcut = "cutService()",throwing = "e")
    public void doAfterThrowing(JoinPoint point,Throwable e){
        try {
            handle(point,null,"loginInfo",null,e);
        }catch(Exception ex){
            log.info("日志记录错误",ex);
        }
    }

    private void handle(JoinPoint point, Object o, String loginInfo, Object s, Throwable e) throws Exception {
        //获取拦截的方法名
        Signature sig = point.getSignature();
        MethodSignature msig = null;
        if (!(sig instanceof MethodSignature)){
            throw new IllegalArgumentException();
        }
        msig = (MethodSignature) sig;
        Object target = point.getTarget();
        Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
        String methodName = currentMethod.getName();
        //获取拦截方法的参数
        Object[] params = point.getArgs();
        //获取操作的名称
        ControllerLog annotation = currentMethod.getAnnotation(ControllerLog.class);
        String moduleName = annotation.moduleName();
        String operationName = annotation.value();
        OperationLogDto operationLog = OperationLogDto.builder()
                .modualName(moduleName)
                .startTime(new Date())
                .build();
        if (!StringUtils.isEmpty(loginInfo)){
            operationLog.setCreateName(loginInfo);
        }
        operationLogService.save(operationLog);

    }

}
